package ar.edu.unq.persistencia.Ruleta;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import ar.edu.unq.persistencia.apuesta.Apuesta;
import ar.edu.unq.persistencia.apuesta.TipoApuesta;
import ar.edu.unq.persistencia.jugador.Jugador;
import ar.edu.unq.persistencia.jugador.Persona;

public class Mesa {

    private static final String JUGADORES = "jugadores";

    private static final String APUESTAS = "apuestasActuales";

    public static final String JUGADORACTUAL = "jugadorActual";

    private Jugador jugadorActual;

    private int numeroActual;

    private static Set numeros = new HashSet(37);

    private Ruleta ruleta = new Ruleta();

    private LinkedList<Jugador> jugadores = new LinkedList<Jugador>();

    private int fichasTotales;

    private List<Apuesta> apuestasActuales = new LinkedList<Apuesta>();

    private List<Apuesta> apuestasTotales = new LinkedList<Apuesta>();

    private boolean yaGiro;

    private int cantidadDeJugadoresPermitidos = 2;

    private int cantidadDeJugadoresActualmente = 0;

    /* CONSTRUCTORES */

    public Mesa(final int i) {
        this.setJugadores(this.jugadores);
        this.fichasTotales = i;
    }

    /* GETTERS AND SETTERS */

    public Mesa() {

    }

    public int getNumeroActual() {
        return this.numeroActual;
    }

    public void setNumeroActual(final int numeroActual) {
        this.numeroActual = numeroActual;
    }

    public static Set getNumeros() {
        return numeros;
    }

    public static void setNumeros(final Set numeros) {
        Mesa.numeros = numeros;
    }

    public List<Apuesta> getApuestasTotales() {
        return this.apuestasTotales;
    }

    public void setApuestasTotales(final List<Apuesta> apuestasTotales) {
        this.apuestasTotales = apuestasTotales;
    }

    public Ruleta getRuleta() {
        return this.ruleta;
    }

    public void setRuleta(final Ruleta ruleta) {
        this.ruleta = ruleta;
    }

    public int getFichasTotales() {
        return this.fichasTotales;
    }

    public void setFichasTotales(final int fichasTotales) {
        this.fichasTotales = fichasTotales;
    }

    public List<Apuesta> getApuestasActuales() {
        return this.apuestasActuales;
    }

    public void setApuestasActuales(final List<Apuesta> apuestasActuales) {
        this.apuestasActuales = apuestasActuales;
    }

    public void setJugadores(final LinkedList<Jugador> jugadores) {
        this.jugadores = jugadores;
    }

    public LinkedList<Jugador> getJugadores() {
        return this.jugadores;
    }

    /* METODOS */

    public void registrarJugador(final String nombre, final int cant) {

        Persona pers = new Persona(nombre, cant);
        Jugador jug = new Jugador(pers);
        this.agregarJugador(jug);

    }

    public void agregarJugador(final Jugador j) {

        this.jugadores.add(j);
        this.cantidadDeJugadoresActualmente += 1;
        System.out.println("Se agrego a " + j.getNombre() + " correctamente");

    }

    public boolean hayLugarDisponible() {
        return this.cantidadDeJugadoresPermitidos > this.cantidadDeJugadoresActualmente;
    }

    public int girar() {
        int numeroGanador = this.ruleta.girar();
        this.yaGiro = true;

        return numeroGanador;

    }

    public void chequearApuestasGanadoras() {

        List<Apuesta> ganadores = new LinkedList<Apuesta>();
        List<Apuesta> perdedores = new LinkedList<Apuesta>();
        for (Apuesta a : this.apuestasActuales) {

            if (a.buscarGanadores(this.numeroActual)) {

                ganadores.add(a);
            } else {
                perdedores.add(a);
            }
        }
        this.pagarApuesta(ganadores);
        this.recolectarDinero(perdedores);
        this.limpiarMesa();
        System.out.println("Las apuestas fueron pagadas correctamente");
    }

    public void chequearApuestasGanadoras(final int numero) {

        List<Apuesta> ganadores = new LinkedList<Apuesta>();
        List<Apuesta> perdedores = new LinkedList<Apuesta>();
        for (Apuesta a : this.apuestasActuales) {

            if (a.buscarGanadores(numero)) {

                ganadores.add(a);
            } else {
                perdedores.add(a);
            }
        }
        this.pagarApuesta(ganadores);
        this.recolectarDinero(perdedores);
        this.limpiarMesa();
        System.out.println("Las apuestas fueron pagadas con éxito");
    }

    private void limpiarMesa() {

        this.apuestasTotales.addAll(this.apuestasActuales);
        this.apuestasActuales.clear();
        this.yaGiro = false;
    }

    private void recolectarDinero(final List<Apuesta> perdedores) {

        for (Apuesta a : perdedores) {

            this.setFichasTotales(this.getFichasTotales() + a.getCantidad());
        }
    }

    public void pagarApuesta(final List<Apuesta> ganadores) {

        for (Apuesta apuesta : ganadores) {
            int aPagar = apuesta.cuantoPagas();
            apuesta.getApostador().cobra(aPagar + apuesta.getCantidad());
            this.setFichasTotales(this.getFichasTotales() - aPagar);
        }

    }

    public Jugador obtenerJugador(final int nro) {

        return this.jugadores.get(nro);

    }

    public void apostar(final Jugador j, final TipoApuesta tipo, final int nro, final int cantFichas) {

        if (cantFichas <= j.getFichas()) {
            Apuesta actual = new Apuesta(j, tipo, nro, cantFichas);
            this.apuestasActuales.add(actual);
            j.setFichas(j.getFichas() - cantFichas);

            //
        } else {
            System.out.println("No te da la tarasca");
        }

    }

    public List<Apuesta> obtenerApuestasDe(final Jugador j) {

        List<Apuesta> resultado = new LinkedList<Apuesta>();
        for (Apuesta a : this.apuestasActuales) {

            if (a.getApostador().equals(j)) {

                resultado.add(a);

            }

        }

        return resultado;

    }

    public int cantidadDeJugadores() {

        return this.jugadores.size();
    }

    public void noVaMas() {

        int resultado = this.girar();
        System.out.println(resultado);

    }

    public void unirse(final Persona unaPersona) {

        Jugador player = new Jugador(unaPersona);
        this.agregarJugador(player);

    }

    public void retirarse(final Jugador jugador) {

        this.jugadores.remove(jugador);

    }

    public Jugador getJugadorCambiado(final Jugador unJugador) {

        for (Jugador j : this.jugadores) {

            if (j.equals(unJugador)) {

                return j;

            }

        }

        return unJugador;

    }

    public boolean isPuedeGirar() {

        return !this.apuestasActuales.isEmpty() && !this.yaGiro;
    }

    public boolean isDeboPagar() {
        return this.yaGiro;

    }

    public void setJugadorActual(final Jugador jugadorActual) {
        this.jugadorActual = jugadorActual;
    }

    public Jugador getJugadorActual() {
        return this.jugadorActual;
    }

    public Jugador getJugador() {
        // TODO Auto-generated method stub
        return this.jugadores.get(0);
    }

}
